package com.azh.server.datam.pagecache;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.RandomAccessFile;
import java.nio.channels.FileChannel;

import com.azh.server.datam.page.Page;
import com.azh.server.util.ExceptionUtils;
import com.azh.server.util.FileCommonUtils;

/**
 * @author zhaozhenhang <zhaozhenhang@kuaishou.com>
 * Created on 2022-04-25
 */
public interface PageCache {
    /**
     * 每页8kb
     */
    public static final int PAGE_SIZE = 1 << 13;

    public int newPage(byte[] initData);

    public Page getPage(int pageNumber) throws Exception;

    public void close();

    public void release(Page page);

    public void truncateBytePageNumber(int maxPageNumber);

    public int getPageNumber();

    public void flushPage(Page page);

    public static PageCacheImpl create(String path, long memory) {
        File file = new File(path + PageCacheImpl.db_suffix);
        try {
            if (!file.createNewFile()) {
                ExceptionUtils.getMessage(new FileNotFoundException("File already exists!"));
            }
        } catch (Exception e) {
            ExceptionUtils.getMessage(e);
        }
        if (FileCommonUtils.canReadOrWrite(file)) {
            ExceptionUtils.getMessage(new RuntimeException("File cannot read or write!"));
        }
        FileChannel channel = null;
        RandomAccessFile refFile = null;
        try {
            refFile = new RandomAccessFile(file, "rw");
            channel = refFile.getChannel();
        } catch (FileNotFoundException e) {
            ExceptionUtils.getMessage(e);
        }
        return new PageCacheImpl(refFile, channel, (int) (memory / PAGE_SIZE));
    }

    public static PageCacheImpl open(String path, long memory) {
        File file = new File(path + PageCacheImpl.db_suffix);
        if (!file.exists()) {
            ExceptionUtils.getMessage(new FileNotFoundException("File not exists!"));
        }
        if (FileCommonUtils.canReadOrWrite(file)) {
            ExceptionUtils.getMessage(new RuntimeException("File cannot read or write!"));
        }
        FileChannel channel = null;
        RandomAccessFile refFile = null;
        try {
            refFile = new RandomAccessFile(file, "rw");
            channel = refFile.getChannel();
        } catch (FileNotFoundException e) {
            ExceptionUtils.getMessage(e);
        }
        return new PageCacheImpl(refFile, channel, (int) (memory / PAGE_SIZE));
    }


}
